<?php

include('database.php');

// GLOBALS
$top_level_domain = 'http://www.megumi-online.com';

$G = array_map(mysql_real_escape_string, $_GET);
$user = user();
$user_main = user() . '_main';
$domain = (empty($G['domain'])) ? $user_main : $G['domain'];
$line = $G['line'];
$vars = array('Var1', 'Var2', 'Var3', 'Var4', 'Var5', 'Var6');
$all_vars = array('Var1', 'Var2', 'Var3', 'Var4', 'Var5', 'Var6', 'Var1_Text', 'Var2_Text', 'Var3_Text', 'Var4_Text', 'Var5_Text', 'Var6_Text');

function sql_exec($sql)
{
	$result = mysql_query($sql) or die ("could not $sql: " . mysql_error() . "\n");
	return $result;
}

function sql_row1($sql)
{
	$result = mysql_query($sql) or die ("could not $sql: " . mysql_error() . "\n");
	$row = mysql_fetch_array($result, MYSQL_ASSOC);
	return $row;
}

function html_header($title)
{
	echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<title>'.$title.'</title> 
	<link rel="stylesheet" href="style.css" type="text/css" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>';
}

function html_header_for_user($title)
{
	global $user;
	$header = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<title>'.$title.'</title> 
	<link rel="stylesheet" href="user_style.css" type="text/css" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head><body>';
	// generate a header from the title
	$header .= '<div id="container">';
	$header .= '<div id="header"><h1>' . $title . '</h1></div>';
	// also add the sidebar here, put the links to all non-form-script pages here
	$sidebar = '<div id="sidebar">' . "\n" . "<ul>\n";
	$scripts = sql_exec("SELECT * FROM Definitions WHERE User='$user' ORDER BY English_Name");
	while ($script = mysql_fetch_array($scripts))
	{
		$filename = $script['Fxn_Call'];
		$filename .= '.php';
		$english_name = $script['English_Name'];
		
		// this is ugly.  the name should be unique
		if ($english_name == $title)
		{
			$blurb = $script['Description'];
			$blurb = htmlentities($blurb, ENT_QUOTES);
		}
		
		// filter out the scripts that forms throw to
		if (strpos($filename, 'form_') !== 0)
		{
			$sidebar .= "<li><a href=\"$filename\">$english_name</a></li>\n";
		}
	}
	$sidebar .= '</ul>' . "\n";
	
	// add blurb and contact information
	$blurb_and_contact = sql_row1("SELECT Blurb, Email FROM Users WHERE User='$user' ");
	$email = $blurb_and_contact['Email'];
	//$blurb =  $blurb_and_contact['Blurb'];
	//$blurb = $script['Description'];
	if (!empty($email))
	{
		$contact = "<p><a href=\"mailto:$email\">Contact</a></p>";
	} else {
		$contact = '';
	}
	$sidebar .= '<div id="blurb_and_contact">' . "\n" . "<p>$blurb</p>\n$contact\n</div>\n";
	
	$sidebar .= '</div>' . "\n";
	
	$header .= $sidebar;
	// add body div opening
	$header .= "<div id=\"body\">\n";
	$code = "echo '$header';\n";
	return $code;
}

function html_footer_for_user()
{
	global $user;
	// end body div
	$html .= "\n\n</div>\n";
	//$html .= "<div id=\\\"footer\\\">$user made this.</div>\n";
	// end container div
	$html .= "\n\n</div>\n";
	$html .= "</body></html>";
	$code = "echo \"$html\";\n";
	return $code;
}

function substru($str,$from,$len)
{
    return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'. $from .'}'.'((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'. $len .'}).*#s','$1', $str);
}

function truncate($text, $length)
{
	return $text;
}

// retrieve value of literal or name of variable given its position (Main, Line 3, Var3)
function display_variable($domain, $line, $name)
{
	// display constant if it exists
	global $user;
	$result = sql_exec("SELECT * FROM Vals WHERE Domain='$domain' AND Line_Number='$line' AND Var_Name='$name' AND User='$user' ");
	if (mysql_num_rows($result) > 0)
	{
		$display = mysql_result($result, 0, 'Value');
		$display = stripslashes($display);
		//die('there was a constant');
		return $display;
	} else {
		// look for a variable
		$name_text = $name . '_Text';
		// first, return with null string if no variables have been saved
		if ($name != 'Returns_To')
		{
			$result = sql_exec("SELECT $name, $name_text FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user' AND ($name IS NOT NULL OR $name_text IS NOT NULL) ");
		} else {
			$result = sql_exec("SELECT $name FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user' AND $name IS NOT NULL");
		}
		if (mysql_num_rows($result) == 0)
		{
			return '';
		}
		
		// there is something in varx or varx_text	
		$result = sql_exec("SELECT $name FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user' AND $name IS NOT NULL");
		if (mysql_num_rows($result) > 0)
		{
			// there is a variable Varx
			$row = mysql_fetch_array($result, MYSQL_ASSOC);
			$variable_id = $row[$name];
			$sql = "SELECT * FROM Variables WHERE ID='$variable_id'";
			$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
			$row = mysql_fetch_array($result, MYSQL_ASSOC);
			// fixes the problem of: it\'s a variable
			$display = stripslashes($row['Name']);
		} else {
			// the variable is Varx_text instead
			$sql = "SELECT $name_text FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user'";
			$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
			// parse name and convert it to the compile.php format
			// we expect the thing in Varx_Text to be a field from a table 
			// it should look like "_loop_" . $ordinals[$table] . "_of_" . $table . "_field_" . $column
			// and should be turned into $loopx_table[column]
			$varx_text_row = mysql_fetch_array($result);
			if (!empty($varx_text_row))
			{
				$variable = array_pop($varx_text_row);
			} else {
				$variable == '';
			}
			// it may be a table field or a form field.  since a table field starts with _loop_, look for that
			
			if (strpos($variable, '_loop_') === FALSE)
			{
				$display = $variable;
			} else {
				$variable = substr($variable, strlen('_loop_'));
				$ordinal = substr($variable, 0, strpos($variable, '_'));
				$variable = substr($variable, strpos($variable, '_of_')+strlen('_of_'));
				$table = remove_userno(substr($variable, 0, strpos($variable, "_field_")));
				$column = substr($variable, strpos($variable, "_field_")+strlen('_field_'));
				$display = "$column@$table ($ordinal)";
			}
		}
		return $display;
	} // end if there are constants
}

// retrieve value of literal or name of variable given its position (Main, Line 3, Var3)
// if it is a variable, add $ in front
// >> if it is a table variable, return the '$row['var']' reference for normal variables, and 
// >> something more complicated for return values
function display_variable_for_code($domain, $line, $name)
{
	// display constant if it exists
	
	// see if this is a form field, in which case the domain should be different
	
	$user = user();
	$val_sql = "SELECT * FROM Vals WHERE Domain='$domain'";
	$val_sql .= " AND Line_Number='$line' AND Var_Name='$name' AND User='$user'";
	$result = mysql_query($val_sql) or die("could not $val_sql: " . mysql_error());
	if (mysql_num_rows($result) > 0)
	{
		$display = mysql_result($result, 0, 'Value');
		
		if (!is_numeric($display))
		{
			// the thing below might have caused ' it\\'s ... '
			// we might have dealt with the apostrophe problem here but will do it in compile instead
			// we still need to deal with ' becoming \'
			$display = stripslashes($display);
		}
	} else {
		// it is not a constant
		$sql = "SELECT $name FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user' AND $name IS NOT NULL";
		$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
		if (mysql_num_rows($result) > 0)
		{
			// there is something not NULL for Varx
			$varx = mysql_fetch_array($result, MYSQL_ASSOC);
			$variable_id = $varx[$name];
			$variable = sql_row1("SELECT * FROM Variables WHERE ID='$variable_id' ");
			//$display = format_as_variable($row['Name'], $variable_id);
			$display = '$var' . $variable_id;
		} else { // assume that there is something in Varx_Text instead
			if ($name != 'Returns_To')
			{
				$name .= '_Text';
				$sql = "SELECT $name FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user' AND $name IS NOT NULL";
				$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
				if (mysql_num_rows($result) == 0)
				{
					//die("the variable appears to be empty");
					return;
				}
				// it may be a table field or a form field
				// a table field should start with _loop_ so anything else is a form field which should be
				// mapped like this: field => $G['$field'];
				
				// parse name and convert it to the compile.php format
				// we expect the thing in Varx_Text to be a field from a table 
				// it should look like "_loop_" . $ordinals[$table] . "_of_" . $table . "_field_" . $column
				// and should be turned into $loopx_table[column]
				$variable = array_pop(mysql_fetch_array($result));
				if (strpos($variable, '_loop_') === FALSE)
				{
					// it is a form field
					$display = '$form_' . $variable;
				} else {
					// it is a table field
					$variable = substr($variable, strlen('_loop_'));
					$ordinal = substr($variable, 0, strpos($variable, '_'));
					$variable = substr($variable, strpos($variable, '_of_')+strlen('_of_'));
					$table = substr($variable, 0, strpos($variable, "_field_"));
					$column = substr($variable, strpos($variable, "_field_")+strlen('_field_'));
					//$display = '$loop' . $ordinal . '_' . $table . '[\'' . $column . '\']';
					$display = '$loop' . $ordinal . '_' . $table . '_' . $column;
					//die($display);
					//$display = '" . ' . $display . ' . "';
				}
			}
		}
	}
	return $display;
}

// this function is meant to be called within compile along with display_variable_for_code, and it
// takes variables like $loop1_table_field['ID'] and turns them into ones like $loop1_table_field_ID, which 
// can be embedded in double-quoted strings
function prep_table_variables($domain, $line)
{		
	global $vars;
	$user = user();
	$set_variables = ''; // this should hold the variable assignments from array references to regular variables
	
	foreach ($vars as $name)
	{
		//$name = 'Var1_Text';
		if ($name != 'Returns_To')
		{
			$name .= '_Text';
			$sql = "SELECT $name, Fxn_Call FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user' AND $name IS NOT NULL";
			$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
			if (mysql_num_rows($result) > 0)
			{
				// it may be a table field or a form field
				// a table field should start with _loop_ so anything else is a form field which should be
				// mapped like this: field => $G['$field'];

				// parse name and convert it to the compile.php format
				// we expect the thing in Varx_Text to be a field from a table 
				// it should look like "_loop_" . $ordinals[$table] . "_of_" . $table . "_field_" . $column
				// and should be turned into $loopx_table[column]
				$row = mysql_fetch_array($result);
				$variable = $row[$name];
				$call = $row['Fxn_Call'];
				if (strpos($variable, '_loop_') === FALSE)
				{
					// it is a form field
					// form fields will only be in Var1_Text, and the caption is in Var2_Text and shouldn't 
					// be messed with
					if (($call == 'form_input' && $name == 'Var1_Text') || $call != 'form_input' )
					{
						$display = '$G[\'' . $variable . '\']';
						$set_variables .= '$form_' . $variable . ' = ' . $display . ";\n";
					}
				} else {
					// it is a table field
					$variable = substr($variable, strlen('_loop_'));
					$ordinal = substr($variable, 0, strpos($variable, '_'));
					$variable = substr($variable, strpos($variable, '_of_')+strlen('_of_'));
					$table = substr($variable, 0, strpos($variable, "_field_"));
					$column = substr($variable, strpos($variable, "_field_")+strlen('_field_'));
					$display = '$loop' . $ordinal . '_' . $table . '[\'' . $column . '\']';
					//die($display);
					//$display = '" . ' . $display . ' . "';
					$set_variables .= '$loop' . $ordinal . '_' . $table . '_' . $column . ' = ' . $display . ";\n";
				}
			} // end if there is anything in this result (a Var1_Text, for example)
		} // end if it's not Returns_To
	} // end foreach (go through vars)
	return $set_variables;
}


function display_variable_for_html($domain, $line, $name)
{
	// display constant if it exists
	$user = user();
	$val_sql = "SELECT * FROM Vals WHERE Domain='$domain'";
	$val_sql .= " AND Line_Number='$line' AND Var_Name='$name' AND User='$user'";
	$result = mysql_query($val_sql) or die("could not $val_sql: " . mysql_error());
	if (mysql_num_rows($result) > 0)
	{
		$display = mysql_result($result, 0, 'Value');
		/*
		if (!is_numeric($display))
		{		
			$display = "'" . $display . "'";
		}
		*/
	} else {
		$sql = "SELECT * FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user'";
		$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
		$row = mysql_fetch_array($result, MYSQL_ASSOC);

		$variable_id = $row[$name];
		$sql = "SELECT * FROM Variables WHERE ID='$variable_id'";
		$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
		$row = mysql_fetch_array($result, MYSQL_ASSOC);
		// see if variable is table value or scalar
		
		// see if variable is return value
		if ($name != 'Returns_To')
		{
			$display = $row['Name'];
		} else {
			$display = '$RESERVED_return';
		}

	}
	return $display;
}


// this should be unnecessary now
function store_if_table_return($domain, $line, $table_name)
{
	global $user;
	$name = 'Returns_To';
	$sql = "SELECT * FROM Instances WHERE Domain='$domain' AND Line_Number='$line' AND User='$user'";
	$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
	$row = mysql_fetch_array($result, MYSQL_ASSOC);
	$variable_id = $row[$name];
	$sql = "SELECT * FROM Variables WHERE ID='$variable_id'";
	$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
	$row = mysql_fetch_array($result, MYSQL_ASSOC);
	
	if (!empty($row['User_Table']))
	{
		$sql = '"' . 'REPLACE INTO Variables SET User_Table_Value=\'$RESERVED_return\' WHERE ID=' . $variable_id . '"';
		$code = "\nmysql_query($sql);\n";
		$code .= '$sql = "SELECT * FROM Variables WHERE User_Table=' . "'" . $table_name . "'";
		$code .= ' AND Name IS NOT NULL AND User_Table_Row IS NOT NULL ORDER BY User_Table_Row, Name";' . "\n";
		$code .= '$' . $table_name . '_result = mysql_query($sql) or die("could not $sql: " . mysql_error());' . "\n";
		$code .= '$' . $table_name . ' = mysql_fetch_array($' . $table_name . '_result, MYSQL_ASSOC);' . "\n";
		return $code;
	} else {
		return '';
	}
}

function user()
{
	return 'user';
}

function is_alphanumeric($string)
{
	$subject = $string;
	$pattern = '/\W/';
	preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE, 3);
	if (count($matches) > 0)
	{
		return FALSE;
	} else {
		return TRUE;
	}
}



function remove_userno($text)
{
	$userno = user() . 'no';
	$pos = strpos($text, $userno);
	if ($pos === 0)
	{
		$text = substr($text, strlen($userno));
	}
	return $text;
}

function header_div()
{
	//echo '<div id="header"><img src="megumi.jpg" alt="megumi" /></div>';
	echo '<div id="header"><h3>m. online</h3></div>';
}

function ctl_struct($call)
{
	$control_structures = array('if', 'while', 'database', 'for', 'ul', 'ol', 'select', 'form', 'p');
	return in_array($call, $control_structures);
}

function end_ctl_struct($call)
{
	$end_control_structures = array('endif', 'endwhile', 'enddb', 'endfor', 'endul', 'endol', 'endselect', 'endform', 'endp');
	return in_array($call, $end_control_structures);
}

function thereis_constant($domain, $line, $user, $var_name)
{
	$constant_result = sql_exec("SELECT * FROM Vals WHERE User='$user' AND Domain='$domain' AND Line_Number='$line' AND Var_Name='$var_name'");
	if (mysql_num_rows($constant_result) > 0)
	{
		return TRUE;
	} else {
		return FALSE;
	}
}

function constant_value($domain, $line, $user, $var_name)
{
	$constant_result = sql_exec("SELECT * FROM Vals WHERE User='$user' AND Domain='$domain' AND Line_Number='$line' AND Var_Name='$var_name'");
	$value = mysql_result($constant_result, 0, 'Value');
	$value = stripslashes($value);
	return $value;
}

function already_set($name, $value)
{
	global $line, $domain;
	$user = user();

	$sql = "SELECT * FROM Instances WHERE $name='$value' AND Domain='$domain' AND Line_Number='$line' AND User='$user' ";
	$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
	$success = mysql_num_rows($result);	

	if ( !empty($success) ) 
	{
		return TRUE;
	} else {
		return FALSE;
	}
}

function optional($arg, $fxn_call)
{
	global $line, $domain;
	$user = user();
	
	switch ($arg) {
	case 'Var1':
		$n = 1;
		break;
	case 'Var2':
		$n = 2;
		break;
	case 'Var3':
		$n = 3;
		break;
	case 'Var4':
		$n = 4;
		break;
	case 'Var5':
		$n = 5;
		break;
	case 'Var6':
		$n = 6;
		break;
	case 'Returns_To':
		$n = 100;
		break;
	}
	
	$sql = "SELECT * FROM Definitions WHERE Fxn_Call='$fxn_call' ";
	$result = mysql_query($sql) or die("could not $sql: " . mysql_error());
	$row = mysql_fetch_array($result, MYSQL_ASSOC);
	//die(var_dump($row));
	
	$required = $row['Required'];
	if (!empty($required))
	{
		if ($n > $required || $arg == 'Returns_To')
		{
			// is optional
			return TRUE;
		} else {
			// is not optional
			return FALSE;
		}
	} else {
		// if no required value, all variables are required
		return FALSE;
	}
}

function round_up($number, $base)
{
	$remainder = $number%$base;
	if ($remainder > 0)
	{
		$number += ($base-$remainder);
	}
	return $number;
}

function round_down($number, $base)
{
	return ($number-($number%$base));
}

function instance_uri($fxn_call, $line)
{
	global $domain, $G;
	switch ($fxn_call) {
	case 'database':
		$uri = "go_through_table.php";
		break;
	case 'database_store':
		$uri = "edit_table_input.php";
		break;
	case 'store_in_table':
		$table = $G['table'];
		$uri = 'store_in_table.php?table=' . $table . '&domain=' . $domain . '&line=' . $line;
		return $uri;
		break;
	case 'delete_from_table':
		$table = $G['table'];
		$uri = 'delete_from_table.php?table=' . $table . '&domain=' . $domain . '&line=' . $line;
		return $uri;
		break;
	case 'form':
		$uri = 'form.php';
		break;
	case 'endform':
		$uri = 'endform.php';
		break;
	case 'form_input':
		$uri = 'form_input.php';
		break;
	case 'select':
		$uri = 'select.php';
		break;
	case 'store_constant':
		$uri = 'store_constant.php';
		break;
	default:
		$uri = "edit_instance.php";
	}
	$uri .= "?domain=$domain&line=$line";
	return $uri;
}

function format_as_variable($nasty, $unique_number)
{
	global $domain;
	$nice = '';
	// $this is reserved in PHP
	// starts with letter or underscore and after that any number of letters, numbers, or underscores
	
	$nasty = str_replace(' ', '_', $nasty);
	
	while (strlen($nasty) > 0)
	{
		$char = substru($nasty, 0, 1);
		$nasty = substru($nasty, 1);
		// a stands for ascii_value
		$a = ord($char);
		if (empty($nice))
		{
			if ( (($a > 64) && ($a < 91)) || (($a > 96) && ($a < 123)) || (($a > 126) && ($a < 256)) || $a == 95 ) 
			{
				$nice .= $char;
			}
		} else {
			if ( (($a > 47) && ($a < 58)) || (($a > 64) && ($a < 91)) || (($a > 96) && ($a < 123)) || (($a > 126) && ($a < 256)) || $a == 95 )
			{
				$nice .= $char;
			}
		} 
	}
	$nice .=  '_' . $domain . '_' . $unique_number;
	
	return $nice;
}

function footer()
{
	$html = '';
	$html .= '<div id="footer">';
	$html .= '<p><a href="mailto:me@megumi-online.com">send me some email</a></p>';
	$html .= '<p><a href="disclaimer.php">this web site sucks</a></p>';
	$html .= '<p><a href="http://code.google.com/p/megumi-online/">project home page</a></p>';
	$html .= '</div>';
	return $html;
}

function get_form_variables($domain)
{
	// go through all instances ordered by domain and then by line,
	// looking for any form fields that come after a form opening tag 
	// that points to this domain
	$variables = array();
	$user = user();
	
	$sql = "SELECT * FROM Instances WHERE User='$user' ORDER BY Domain, Line_Number";
	$result = sql_exec($sql);
	$form_destination = '';
	$form_destination_ID = 0;
	while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
	{
		$function_call = $row['Fxn_Call'];
		if ($function_call == 'form')
		{
			$form_destination_ID = $row['Var1'];
			// retrieve the Fxn_Call of the function with this ID
			$sql2 = "SELECT * FROM Definitions WHERE ID='$form_destination_ID' ";
			$def = sql_row1($sql2);
			$form_destination = $def['Fxn_Call'];
		}
		
		if ($function_call == 'form_input') // TODO: expand this list to include the other form items
		{
			if ($form_destination == $domain)
			{
				// key => value pairs where key is the source function's domain and the value is the array of variables
				// (as names not IDs) that are being sent to this domain via the forms in the source function
				// or maybe value is source_domain.field_name and key is automatic (0,1,2,...n)
				$form_domain = $row['Domain'];
				$form_english_name = stripslashes($def['English_Name']);
				$field_id = $row['Var1'];
				$line_here = $row['Line_Number'];
				// grab the field name with the same code i use to label the buttons normally, with a few changes
				// if a constant is defined for this argument, use that instead of 'Constant'
				if (thereis_constant($form_domain, $line_here, $user, 'Var1') == TRUE)
				{
					$button_text = constant_value($form_domain, $line_here, $user, 'Var1');
				} else {
					$button_text = $name;
				}
				$form_field = $button_text;
				$full_field_name = $form_english_name . ': ' . $form_field;
				die(var_dump($row));
				$variables[] = array($row['ID'], $full_field_name);
			}
		}
	}
	return $variables;
}

function web_page($title, $content)
{
	$page = html_header($title);
	$page .= '<body><div id="container"><div id="header"><img src="megumi_banner.png" /></div><div id="body">';
	$page .= $content;
	$page .= '</div>' . footer() . '</div></body></html>';
	return $page;
}

// get the table 
function store_in_table_table($bonus_field)
{
	//die($bonus_field);
	$lob_off_front = strlen("INSERT INTO ");
	$bonus_field = substr($bonus_field, $lob_off_front);
	$end_point = strpos($bonus_field, ' ');
	if ($end_point > 0)
	{
		$bonus_field = substr($bonus_field, 0, $end_point);
	}
	//die($bonus_field);
	return $bonus_field;
}

// this returns a list of the available tables as an array
// the rows are pushed to and popped from the array as a stack
function available_tables($user, $domain, $line)
{
	$result = sql_exec("SELECT * FROM Instances WHERE User='$user' AND Domain='$domain' AND Line_Number<'$line' ORDER BY Line_Number");
	$tables_stack = array();
	while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
	{
		if ($row['Fxn_Call'] == 'database')
		{
			$parsed = parse_query($row['Bonus_Field']);
			$table = $parsed['table'];
			array_push($tables_stack, $table);
		}
		if ($row['Fxn_Call'] == 'enddb')
		{
			array_pop($tables_stack);
		}
	}
	return $tables_stack;
}

// returns an array of all the table values ($row type arrays) available at this line
function available_table_values($user, $domain, $line)
{
	$values = array();
	$tables_stack = available_tables($user, $domain, $line);
	$ordinals = array_count_values($tables_stack); 
	$tables_stack = array_reverse($tables_stack); // so we can count down
	foreach ($tables_stack as $table)
	{
		$result = sql_exec("SHOW COLUMNS FROM $table");
		while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
		{
			$column = $row['Field'];
			// $values[] = "_loop_" . $ordinals[$table] . "_of_table_" . $table;
			// $value_in_db = $table . '-' . $ordinals[$table] . '-' . $column;
			$value_in_db = "_loop_" . $ordinals[$table] . "_of_" . $table . "_field_" . $column;
			// $value_to_user = remove_userno($table) . '-' . $ordinals[$table] . '-' . $column;
			$value_to_user = $column . '@' . remove_userno($table) . " ($ordinals[$table])";
			$values[$value_in_db] = $value_to_user;
		}
		$ordinals[$table] = $ordinals[$table] - 1;
	}
	$values = array_reverse($values);
	//die(var_dump($values));
	return $values;
}

// parses the MySQL query 
function parse_query($query)
{
	$parsed = array();
	$query = substr($query, strlen('SELECT * FROM '));
	if (strpos($query, ' ') === FALSE)
	{
		$parsed['table'] = $query;
	} else {
		$parsed['table'] = substr($query, 0, strpos($query, ' '));
		$query = substr($query, strpos($query, ' '));
		
		if (strpos($query, 'WHERE ') !== FALSE)
		{
			// parse the WHERE clause
			// this could wait since a regular 'if' statement later on could accomplish the same thing
		}
		
		if (strpos($query, 'ORDER BY ') !== FALSE)
		{
			// parse the ORDER BY clause
			$order_by = substr($query, strlen('ORDER BY '));
			//$parsed['order_by'] = explode(', ', $order_by);
			// we might get something like Field ASC
			$order_by = trim($order_by);
			$parsed['order_by'] = substr($order_by, 0, strpos($order_by, ' '));
		}
	}
	return $parsed;
}

// if this page was called, we can be sure that something about this domain was updated, so update the Updated field
// when to do it depends on if something was deleted or not -- don't update a timestamp and then delete its row
function update($user, $domain, $line)
{
	// check that the line in question exists, and if it doesn't, just update the first line
	$target_line_result = sql_exec("SELECT * FROM Instances WHERE User='$user' AND Domain='$domain' AND Line_Number='$line' ");
	if (mysql_num_rows($target_line_result) > 0)
	{
		sql_exec("UPDATE Instances SET Updated=UNIX_TIMESTAMP() WHERE User='$user' AND Domain='$domain' AND Line_Number='$line'");
	} else {
		$first_line = sql_row1("SELECT * FROM Instances WHERE User='$user' AND Domain='$domain' ORDER BY Line_Number ");
		sql_exec("UPDATE Instances SET Updated=UNIX_TIMESTAMP() WHERE User='$user' AND Domain='$domain' AND Line_Number='$first_line'");
	}
	compile();
}

function focus_onload($user, $domain)
{
	$result = sql_exec("SELECT Line_Number FROM Instances WHERE User='$user' AND Domain='$domain' ORDER BY Updated DESC");
	if (mysql_num_rows($result) > 0)
	{
		$row = mysql_fetch_array($result);
		$id = 'Line' . $row['Line_Number'];
		$onload = ' onload="focus_on_updated(\''.$id.'\')" ';
		return $onload;
	} else {
		return '';
	}
}

function most_recent_domain($user)
{
	$result = sql_exec("SELECT Domain FROM Instances WHERE User='$user' ORDER BY Updated DESC");
	if (mysql_num_rows($result) > 0)
	{
		$row = mysql_fetch_array($result);
		$domain = array_pop($row);
		return $domain;
	} else {
		return $user . '_main';
	}
}

// this may or may not be a good idea
// finds the domain of the script with the most recent update to its
// Updated field
function get_current_fxn_name()
{
	// 'Current' is not a helpful name for the current function, so retrieve the actual function name for the button
	$user = user();
	$result = sql_exec("SELECT Domain FROM Instances WHERE User='$user' ORDER BY Updated DESC");
	if (mysql_num_rows($result) > 0)
	{
		$row = mysql_fetch_array($result);
		$domain = array_pop($row);
		$fxn_name_sql = "SELECT English_Name FROM Definitions WHERE User='$user' and Fxn_Call='$domain' ";
		//die($fxn_name_sql);
		$result = mysql_query($fxn_name_sql);
		if ($row = mysql_fetch_array($result))
		{
			$current_fxn_name = truncate(array_pop($row), 13);
		}
		return $current_fxn_name;
	} else {
		return 'Home';
	}
}




function equality($var1_value, $var2_id, $var3_value)
{
	switch ($var2_id) {
	case -1:
		$operator = '=';
		break;
	case -2:
		$operator = '≠';
		break;
	case -3:
		$operator = '<';
		break;
	case -4:
		$operator = '≤';
		break;
	case -5:
		$operator = '≥';
		break;
	case -6:
		$operator = '>';
		break;
	}
	
	$limit = 7;
	
	$text = truncate($var1_value, $limit) . ' ' . $operator . ' ' . truncate($var3_value, $limit);
	return $text;
}

// write out the expression in one line and keep each side from taking up more than half the length
function arithmetical_expression($var1_value, $var2_id, $var3_value)
{
	if (!empty($var1_value) && !empty($var3_value))
	{
		switch ($var2_id) {
		case -7:
			$operator = '+';
			break;
		case -8:
			$operator = '−';
			break;
		case -9:
			$operator = '×';
			break;
		case -10:
			$operator = '÷';
			break;
		}
	
		$text = "$var1_value $operator $var3_value";
		return $text;
	} else {
		return '[Incomplete]';
	}
}


function check_for_indent()
{
	global $domain, $line, $user;
	if ($_GET['add_indent'] == 'yes')
	{
		// switch lines in this domain
		$lower_line = $line;
		$upper_line = $line-1;
		$sql = "UPDATE Instances SET Line_Number='$lower_line' WHERE User='$user' AND Domain='$domain' AND Line_Number='$upper_line'";
		sql_exec($sql);
		$sql = "UPDATE Instances SET Line_Number='$upper_line' WHERE User='$user' AND Domain='$domain' AND Line_Number='$lower_line'";
		sql_exec($sql);
	}

	// only do this if there is something indented
	if ($_GET['remove_indent'] == 'yes')
	{
		// switch lines in this domain
		$lower_line = $line;
		$upper_line = $line-1;
		$sql = "UPDATE Instances SET Line_Number='$lower_line' WHERE User='$user' AND Domain='$domain' AND Line_Number='$upper_line'";
		sql_exec($sql);
		$sql = "UPDATE Instances SET Line_Number='$upper_line' WHERE User='$user' AND Domain='$domain' AND Line_Number='$lower_line'";
		sql_exec($sql);
	}
	
}

function svg_write($height, $width, $interior, $filename, $domain)
{
	global $script, $toolbar_color, $user, $gradient, $style_background;
	$buttons = make_buttons_array($domain);
	$svg = '';
		
	// the gradient
	$svg .= $gradient;
	
	// toolbar
	$button_width = 140;
	$button_padding = 10;
	
	// reload if this script's flowchart has been updated
	$onload = "makeRequestUpdate('freshest_url.php?domain=$domain', '$filename')";
	
	$tb_w = count($buttons)*$button_width + (count($buttons)-3)*($button_padding);
	// toolbar hangs over by 10 on each side
	$svg .= '<rect x="40" y="10" width="' . $tb_w . '" height="70" rx="10" fill="'.$toolbar_color.'" stroke="silver" stroke-width="1" onload="' . $onload . '" onmouseover="darken_everything()">';
	$svg .= '</rect>';
	$svg .= "\n";
	
	// buttons
	$button_x = 50;
	$button_y = 20;
	
	foreach ($buttons as $name => $link)
	{
		$svg .= toolbar_button($button_x, $button_y, $name, $link, $button_width);
		$button_x += $button_width;
	}
	
	$translate_x = 50;
	$svg .= svg_translate($translate_x, 100, $interior);
	$svg .= "\n\n\n</svg>\n";
	
	// must do this at the end so they can include the toolbar etc in calculations
	$height = greatest_y($svg);
	$width = greatest_x($svg);

	// provide a nice background and hopefully solve the annoying javascript bug where it tries to retrieve previousnode
	// and gets null
	$background = '<rect x="0" y="0" width="' . $width . '" height="' . $height . '" fill="'.$style_background.'" onmouseover="darken_everything()"></rect>' . "\n";

	$svg = '<?xml version="1.0" standalone="no" ?>
	<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
	"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
	<svg width="' . $width . 'px" height="' . $height . 'px" version="1.1" 
	xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' . "\n\n\n\n" . $script . "\n" . $background . $svg;
	
	$file = fopen($filename, 'w');
	if ($file === FALSE)
	{
		die("could not open file");
	}
	fwrite($file, $svg);
}

// from the former compile.php

function add_indent($code, $indent)
{
	for ($i = 0; $i < $indent; $i++)
	{
		$tabs .= "\t";
	}
	
	$code = str_replace("\n", "\n$tabs", $code); // lines after the first line
	// remove all the trailing tabs
	while (substr($code, strlen($code)-1) == "\t")
	{
		$code = substr($code, 0, strlen($code)-1);
	}
	$code = $tabs . $code; // the first line
	return $code;
}

function userdef_calls($calls)
{
	$user = user();
	
	foreach ($calls as $domain)
	{
		$result = sql_exec("SELECT * FROM Instances WHERE Domain='$domain' AND User='$user' ");
		while ($row = mysql_fetch_array($result))
		{
			$call = $row['Fxn_Call'];
			if (!in_array($call, $calls))
			{
				//die('call: ' . $call);
				$def = sql_row1("SELECT * FROM Definitions WHERE Fxn_Call='$call' ");
				// if it is user-defined
				if (!is_null($def['User']))
				{
					array_push($calls, $call);
					$calls = userdef_calls($calls);
				}
			}
		}
	}
	
	return $calls;
}

// basically this doesn't do what it needs to do
// it returns a list of the arguments like 'search, replace, text' rather than the real variables like $var3, $var4, $var5
function argument_list($call)
{
	$def = sql_row1("SELECT * FROM Definitions WHERE Fxn_Call='$call' ");
	global $vars;
	foreach ($vars as $v)
	{
		if (!is_null($def[$v]))
		{
			if ($v == 'Var1')
			{
				$list = $def[$v];
			} else {
				$list .= ", " . $def[$v];
			}
		}
	}
	
	return $list;
}

function argument_array($call)
{
	$def = sql_row1("SELECT * FROM Definitions WHERE Fxn_Call='$call' ");
	global $vars, $user;
	$list = array();
	foreach ($vars as $v)
	{
		if (!is_null($def[$v]))
		{
			$name = $def[$v];
			// search for its corresponding variable ID (should have already been made)
			$sql = "SELECT ID FROM Variables WHERE User='$user' AND Domain='$call' and Name='$name'";
			//die($sql);
			//$result = mysql_query($sql) or die(mysql_error());
			//die(var_dump($row));
			//$id = array_pop($row);
			$id = array_pop(sql_row1($sql));
			$list[$id] = $name;
		}
	}
	
	return $list;
}

// this should return the list of the real variables like $var3, $var4, $var5
function new_argument_list($call)
{
	$def = sql_row1("SELECT * FROM Definitions WHERE Fxn_Call='$call' ");
	global $vars, $user;
	foreach ($vars as $v)
	{
		if (!is_null($def[$v]))
		{
			$name = $def[$v];
			// search for its corresponding variable ID (should have already been made)
			$sql = "SELECT ID FROM Variables WHERE User='$user' AND Domain='$call' and Name='$name'";
			//die($sql);
			$result = mysql_query($sql) or die(mysql_error());
			//die(var_dump($row));
			//$id = array_pop($row);
			$row = sql_row1($sql);
			if (empty($row))
			{
				//die($sql);
				// this function's arguments are (I guess) not specified for this one
				// maybe this will break compile() but it wasn't going to work anway so fuck it
			} else {
				$id = array_pop($row);
				if (empty($list))
				{
					$list = '$var' . $id;
				} else {
					$list .= ", " . '$var' . $id;
				}
			}	
		}
	}
	
	return $list;
}

function field_name($id, $position, $clause)
{	
	global $domain, $line, $user;
	
	// it might be -11 (constant)
	if ($id == -11)
	{
		$constant_name = $clause . '.' . $position;
		//die("SELECT Value FROM Vals WHERE Var_Name='$constant_name' AND Domain='$domain' AND User='$user' AND Line_Number='$line' ");
		$row = sql_row1("SELECT Value FROM Vals WHERE Var_Name='$constant_name' AND Domain='$domain' AND User='$user' AND Line_Number='$line' ");
		$constant_value = $row['Value'];
		return $constant_value;
	} else {
		$row = sql_row1("SELECT * FROM Variables WHERE ID='$id'");
		$name = $row['Name'];
		if (!empty($name))
		{
			$name = format_as_variable($name, $id);
			return $name;
		}
	}
}

function sql_comparison_operators($fancy)
{
	// go from the human-readable, traditional style comparison operators in unicode to the forms used by SQL
	switch ($fancy)
	{
		case '≠':
			return '<>';
		case '≤':
			return '<=';
		case '≥':
			return '>=';
		default:
			return $fancy;
			// no conversion for > or < or =
	}
}

// encloses text in HTML paragraph tags
function put_in_p($paragraph_interior)
{
	// escape ' in $paragraph_interior
	$p = '"<p>" . ' . $paragraph_interior . ' . "</p>"';
	return $p;
}

// makes an 'echo' statement 
function echo_statement_out($stmt)
{
	$out = "echo $stmt;";
	return $out;
}

// encloses text in HTML paragraph tag and makes and 'echo' statement for it
function compile_in_p($p)
{
	return echo_statement_out(put_in_p($p));
}

// adapted from available_tables
function all_tables($user, $domain)
{
	$result = sql_exec("SELECT * FROM Instances WHERE User='$user' AND Domain='$domain' ORDER BY Line_Number");
	$tables_stack = array();
	while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
	{
		if ($row['Fxn_Call'] == 'database')
		{
			$parsed = parse_query($row['Bonus_Field']);
			// there seems to be a case where this is called by compile between when the database call is inserted and 
			// the Bonus Field is written, so don't push onto the array when that happens
			if (!empty($parsed['table']))
			{
				array_push($tables_stack, $parsed['table']);
			}
		}
	}
	return $tables_stack;
}

// adapted from available_table_values($user, $domain, $line) in common.php
function old_table_names_for_compile($user, $domain)
{
	//echo "user/domain: $user/$domain";
	$values = array();
	$tables_stack = all_tables($user, $domain);
	if (!empty($tables_stack))
	{
		//die(var_dump($tables_stack));
		//var_dump($tables_stack);
		$ordinals = array_count_values($tables_stack); 
		$tables_stack = array_reverse($tables_stack); // so we can count down
		foreach ($tables_stack as $table)
		{
			// and should be turned into $loopx_table[column]
			$values[] = "loop" . $ordinals[$table] . "_" . $table;
			$ordinals[$table] = $ordinals[$table] - 1;
		}
		//$values = array_reverse($values);
		//die(var_dump($values));
		return $values;
	} else {
		return FALSE;
	}
}

function table_names_for_compile($user, $domain)
{
	$tables_hash = array();
	$complete_names = array();
	$result = sql_exec("SELECT * FROM Instances WHERE (Fxn_Call='database' OR Fxn_Call='enddb') AND User='$user' AND Domain='$domain' ORDER BY Line_Number DESC");
	while ($row = mysql_fetch_array($result))
	{
		if ($row['Fxn_Call'] == 'database')
		{
			$parsed = parse_query($row['Bonus_Field']);
			$table = $parsed['table'];
			if (!empty($table))
			{
				if (array_key_exists($table, $tables_hash) == TRUE)
				{
					$tables_hash[$table] = $tables_hash[$table] + 1;
				} else {
					$tables_hash[$table] = 1;
				}
				$complete_names[] = "loop" . $tables_hash[$table] . "_" . $table;
			}
		} else {
			$tables_hash[$table] = $tables_hash[$table] - 1;
		}			
	}
	// because this was constructed as a stack
	//$complete_names = array_reverse($complete_names);
	return $complete_names;
}

function compile()
{
	global $user, $vars;

	// gather everything that this user has created
	// order by domain, line number

	$result = sql_exec("SELECT * FROM Instances Where User='$user' ORDER BY Domain, Line_Number");


	// compile each domain to a php file and save it
	while($row = mysql_fetch_array($result))
	{
		$domain = $row['Domain'];
		$line = $row['Line_Number'];
		$fxn_call = $row['Fxn_Call'];
		$code = '';
	
		// all the tables retrieved in this domain if is the first line in this domain
		if (empty($everything[$domain]))
		{
			$table_names = table_names_for_compile($user, $domain);
		}
	
		if (end_ctl_struct($fxn_call))
		{
			$indent--;
		}
	
		$def_result = mysql_query("SELECT * FROM Definitions WHERE Fxn_Call='$fxn_call' AND (User='$user' OR User IS NULL)") or die(mysql_error());
		$def = mysql_fetch_array($def_result, MYSQL_ASSOC);
	
		// add line of real code based on data in this row of Instances
		$return = display_variable_for_code($domain, $line, 'Returns_To');
		$v1 = display_variable_for_code($domain, $line, 'Var1');
		$v2 = display_variable_for_code($domain, $line, 'Var2');
		$v3 = display_variable_for_code($domain, $line, 'Var3');
		$v4 = display_variable_for_code($domain, $line, 'Var4');
		$v5 = display_variable_for_code($domain, $line, 'Var5');
		$v6 = display_variable_for_code($domain, $line, 'Var6');
		$v1_html  = display_variable_for_html($domain, $line, 'Var1');
		$v2_html = display_variable_for_html($domain, $line, 'Var2');
		$v3_html = display_variable_for_html($domain, $line, 'Var3');
		$v4_html  = display_variable_for_html($domain, $line, 'Var4');
		$v5_html  = display_variable_for_html($domain, $line, 'Var5');
		$v6_html  = display_variable_for_html($domain, $line, 'Var6');
		
		switch ($fxn_call) {
		case "store":
			$code .= "$v1;";
			break;
		case "concatenate":
			$code .= "$v1 . $v2;";
			break;
		case "arithmetic":
			switch ($row['Var2']) {
			case -7:
				$operator = ' + ';
				break;
			case -8:
				$operator = ' - ';
				break;
			case -9:
				$operator = '*';
				break;
			case -10:
				$operator = '/';
				break;
			}
			$code .= "$v1$operator$v3;";
			break;
		case 'if':
			switch ($row['Var2']) {
			case -1:
				$operator = '==';
				break;
			case -2:
				$operator = '!=';
				break;
			case -3:
				$operator = '<';
				break;
			case -4:
				$operator = '<=';
				break;
			case -5:
				$operator = '>=';
				break;
			case -6:
				$operator = '>';
				break;
			}
			$code .= "if ($v1 $operator $v3)\n{";
			break;
		case 'while':
			switch ($row['Var2']) {
			case -1:
				$operator = '==';
				break;
			case -2:
				$operator = '!=';
				break;
			case -3:
				$operator = '<';
				break;
			case -4:
				$operator = '<=';
				break;
			case -5:
				$operator = '>=';
				break;
			case -6:
				$operator = '>';
				break;
			}
			$code .= "while ($v1 $operator $v3)\n{\n";
			break;
		case 'for':
			// 3 arguments: variable, from, to
			$code .= "for ($v1 = $v2; $v1 <= $v3; $v1++)\n{";
			break;
		case 'database':
			// $table_names was made at the beginning and lists all the tables we will loop through 
			if (!empty($table_names))
			{
				$table_name = array_pop($table_names);
				$query = $row['Bonus_Field'];
				$code .= '$sql = "' . $query . "\";\n";
				$code .= '$' . $table_name . '_result = mysql_query($sql) or die("could not $sql: " . mysql_error());' . "\n";
				$code .= 'while ($' . $table_name . ' = mysql_fetch_array($' . $table_name . '_result, MYSQL_ASSOC))'."\n".'{';
			}
			break;
		case 'store_in_table':
			$code .= '$sql = "' . $row['Bonus_Field'] . '";' . "\n";
			$code .= 'mysql_query($sql) or die("could not $sql: " . mysql_error());';
			break;
		case 'delete_from_table':
			$code .= '$sql = "' . $row['Bonus_Field'] . '";' . "\n";
			$code .= 'mysql_query($sql) or die("could not $sql: " . mysql_error());';
			break;
		case 'echo':
			$code .= "echo \"<p>$v1</p>\n\";";
			break;
		case "endif":
			$code .= "}";
			break;
		case "endwhile":
			$code .= "}";
			break;
		case "enddb":
			$code .= "}";
			break;
		case "endfor":
			$code .= "}";
			break;
		case 'web_page':
			$code .= '\'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
	<head>
		<title>' . $v1_html . '</title> 
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	</head><body>\' . ' . "$v2" . ' . \'</body>' . "\n" . '</html>\'' . ";\n";
			break;
		case 'a':
			$code .= "echo \"<a href=\\\"$v1_html\\\">$v2_html</a>\n\";";
			break;
		case 'select':
			$v2 = $row['Var2_Text'];
			$field_name = $row['Var1_Text'];
			$code .= "echo \"<tr><td>$v2</td><td><select name=\\\"$field_name\\\">\n\";";
			break;
		case 'endselect':
			$code .= "echo \"</select></tr><td>\n\";";
			break;
		case 'option':
			$code .= "echo \"<option name=\\\"$v1_html\\\">$v2</option>\";";
			break;
		case "form":	
			// Var1 is an exception since it holds the ID of a Definition rather than an Instance
			// filenames for PHP files are in the form $domain.php
			$def_id = $row['Var1'];
			$destination_def = sql_row1("SELECT * FROM Definitions WHERE ID='$def_id' ");
			$def_form = $destination_def['Fxn_Call'];
			$form_name = $destination_def['English_Name'];
			$destination_page = $def_form . '.php';
			$code .= "echo \"<form action=\\\"$destination_page\\\" method=\\\"get\\\"><table>\n<h4>$form_name</h4>\";";
			break;
		case "form_input":
			$v1 = $row['Var1_Text'];
			$v2 = $row['Var2_Text'];
			if (!empty($v2))
			{
				$code .= "echo \"<tr><td>$v2</td><td><input name=\\\"$v1\\\" /></td></tr> \n\";";
			} else {
				$code .= "echo \"<tr><td>\" . " . put_in_p('\'<input name="$v1" />\'') . '. "</td></tr>";'; 
			}
			break;
		case 'endform':
			$v1_html = htmlspecialchars($row['Var1_Text']);
			$label = (empty($v1_html) == TRUE) ? '' : " value=\\\"$v1_html\\\" ";
			//$code .= "echo \"<input type=\\\"submit\\\" value=\\\"$label\\\" /></form>\";";
			$code .= "echo \"<tr><td><input type=\\\"submit\\\" value=\\\"Submit\\\" /></td></tr></table></form>\n\";";
			break;
		case 'date':
			//$code .= 'echo date("l, F jS, Y, 
			$code .= 'date("r");';
			break;
		case 'return':
			$code .= 'return ' . $v1 . ';';
			break;
		case 'store_constant':
			$constant = '"' . $row['Bonus_Field'] . '"';
			$code .= "$constant;\n";
			break;
		default:
			// find fxn definition and loop through all variables
			foreach ($vars as $v)
			{
				if (!is_null($def[$v]))
				{
					$next_variable = display_variable_for_code($domain, $line, $v);
					// see if it's a constant and put it in apostrophes if it is
					$thereis_constant = sql_exec("SELECT * FROM Vals WHERE Domain='$domain' AND Line_Number='$line' AND Var_Name='$v' AND User='$user'");
					if (mysql_num_rows($thereis_constant) != 0)
					{
						$next_variable = stripslashes($next_variable);
						$next_variable = str_replace("'", "\'", $next_variable);
						$next_variable = "'" . $next_variable . "'";
					}
					// we need to check that this isn't empty so we don't add a comma before nothing
					// when there is an optional argument that was not specified
					if (!empty($next_variable))
					{
						if (!empty($code))
						{
							$code .= ', ';
						}
						$code .= $next_variable;
					} 
				}
			}
			// we would do this at the beginning but then it would screw up the empty() test above for commas
			$code = $fxn_call . '(' . $code;
		
			$code .= ');';
		}
	
	
	
	
		if (!is_null($def['Returns_To']))
		{
			$code = $return . ' = ' . $code;
		}
	
		// add assignments of array references to normal variables
		$array_references = prep_table_variables($domain, $line);
		$code = $array_references . $code;
		$code = add_indent($code, $indent);
		$code .= "\n";
	
		// update indentation for this line
		if (ctl_struct($fxn_call))
		{
			$indent++;
		}
	
		// add code to domain's array element
		$everything[$domain] .= $code;
	}

	//die(var_dump($everything));
	
	// add the empty functions to $everything so we can have pages for functions with no instances, e.g. 
	// form scripts that haven't been written yet.
	
	$all_defs = sql_exec("SELECT * FROM Definitions WHERE User='$user' ");
	while ($all_defs_def = mysql_fetch_array($all_defs, MYSQL_ASSOC))
	{
		$domain = $all_defs_def['Fxn_Call'];
		if (empty($everything))
		{
			write_empty_page($domain);
		} elseif (array_key_exists($domain, $everything) == FALSE) {
			write_empty_page($domain);
		}
	}

	if (!empty($everything))
	{
		// save everything
		foreach ($everything as $domain=>$code)
		{
			// build library
			$calls = userdef_calls(array($domain));
			//die(var_dump($calls));
			foreach ($calls as $call)
			{
				//die("call/domain: $call/$domain");	
				//if ($call != $domain)
				//{
					$args = new_argument_list($call);
					//die(var_dump($args));
					$code = "function $call($args)\n{\n" . add_indent($everything[$call], 1) . "}\n\n" . $code;
				//}
			}
	
			// header fxn calls: load db (on top of library)
			$html_footer = html_footer_for_user();
			$domain_def = sql_row1("SELECT English_Name FROM Definitions WHERE Fxn_Call='$domain'");
			$title = $domain_def['English_Name'];
			//$escape_get = '$G = array_map(mysql_real_escape_string, $_GET);' . "\n";
			$escape_get = '$G = array_map(stripslashes, $_GET);' . "\n";
			$code = "require('database.php');\n\n" . $escape_get . html_header_for_user($title) . $code . $html_footer;
	
			$filename = $domain . '.php';
			$file = fopen($filename, 'w');
			fwrite($file, "<?php\n\n$code\n\n" . "?" . '>');
			chmod($filename, 0755);
		}
	}
}

// similar to the end of compile(), it writes a page in which there are no instances
function write_empty_page($domain)
{
	// header fxn calls: load db (on top of library)
	$html_footer = html_footer_for_user();
	$domain_def = sql_row1("SELECT English_Name FROM Definitions WHERE Fxn_Call='$domain'");
	$title = $domain_def['English_Name'];
	$code = "require('database.php');\n\n" . html_header_for_user($title) . 'echo "<p>[Empty Page]</p>";' . "\n" . $html_footer;

	$filename = $domain . '.php';
	$file = fopen($filename, 'w');
	fwrite($file, "<?php\n\n$code\n\n" . "?" . '>');
	chmod($filename, 0755);
}

// returns an SQL query which should pull all the instances of form_input which return to this domain
function add_form_fields()
{
	global $user, $domain;
	// this is a domain receiving a form if the domain's definition ID is stored somewhere was Var1 of 
	// an instance which has Fxn_Call set to 'form'
	$def = sql_row1("SELECT * FROM Definitions WHERE User='$user' AND Fxn_Call='$domain' ");
	$def_id = $def['ID'];
	$form_call = sql_exec("SELECT * FROM Instances WHERE Fxn_Call='form' AND Var1='$def_id' ");
	if (mysql_num_rows($form_call) > 0)
	{
		// since the form_input instances do not have the definition ID, find which ones are in the right form 
		// by adding line number limits in the WHERE clause (from 'form' to 'endform' lines)
		$form_call_row = mysql_fetch_array($form_call, MYSQL_ASSOC);
		$form_line = $form_call_row['Line_Number'];
		$form_domain = $form_call_row['Domain']; 
		
		$form_end_row = sql_row1("SELECT Line_Number FROM Instances WHERE Fxn_Call='endform' AND Domain='$form_domain' AND User='$user' AND Line_Number>'$form_line' ORDER BY Line_Number ASC");
		$form_end_line = $form_end_row['Line_Number'];
		
		$sql = "SELECT * FROM Instances WHERE (Fxn_Call='form_input' OR Fxn_Call='select') AND User='$user' AND Domain='$form_domain' AND Line_Number>'$form_line' AND Line_Number<'$form_end_line' ";
		//die($sql);
		return $sql;
	} else {
		return '';
	}
}

// gets the variable that will be deleted in this table, for example $var17 from 
// DELETE FROM jkchannoelmo WHERE lewis='$var17'
function delete_from_table_default($bonus_field)
{
	if (strpos($bonus_field, '=\'') !== FALSE)
	{
		$beginning_point = strpos($bonus_field, '=\'') + strlen('=\'');
		$id = substr($bonus_field, $beginning_point); 
		// also cut off the ' at the end
		$apostrophe = strpos($id, '\'');
		$id = substr($id, 0, $apostrophe);
		//die("$id");

		return $id;
	} 
}

// gets the variable ID that will be deleted in this table, for example 17 from 
// DELETE FROM jkchannoelmo WHERE lewis='$var17'
function delete_from_table_default_id($bonus_field)
{
	$var = delete_from_table_default($bonus_field);
	$id = substr($var, strlen('$var'));
	return $id;
}

// get the table 
// this comes from store_in_table_table in common.php
function delete_from_table_table($bonus_field)
{
	$lob_off_front = strlen("DELETE FROM ");
	$bonus_field = substr($bonus_field, $lob_off_front);
	$end_point = strpos($bonus_field, ' ');
	if ($end_point > 0)
	{
		$bonus_field = substr($bonus_field, 0, $end_point);
	}
	return $bonus_field;
}

// get the field name which should be between 'WHERE ' and '=' in something like WHERE ID='$var9'
function delete_from_table_default_column($bonus_field)
{
	$beginning_string = 'WHERE ';
	$ending_string = '=';
	if (strpos($bonus_field, '=\'') !== FALSE)
	{
		$beginning_point = strpos($bonus_field, $beginning_string) + strlen($beginning_string);
		$column = substr($bonus_field, $beginning_point); 
		// also cut off the ' at the end
		$apostrophe = strpos($column, $ending_string);
		$column = substr($column, 0, $apostrophe);
		//die("$id");

		return $column;
	} 
}


$user = 'user';

?>
